package com.ebt.m.commons.buscomponent.listview;

import android.content.Context;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;

import com.ebt.m.commons.BaseApplication;
import com.ebt.m.commons.utils.Logger;
import com.ebt.m.commons.utils.NetUtils;
import com.ebt.m.commons.buscomponent.listview.ISectionFactory;
import com.ebt.m.commons.buscomponent.listview.IView;
import com.ebt.m.commons.buscomponent.listview.SectionItem;

import java.util.List;

public class BaseRecyclerAdapter extends RecyclerView.Adapter {
    List<SectionItem> list;
    Context context;
    protected ISectionFactory factory;
    private View emptyView;
    private View footerView;
    private View netErrorView;
    private View errorView;

    private boolean isNewLoad = true;
    private boolean isErrorData = false;

    private static final int EMPTY_VIEW = -1;
    private static final int FOOTER_VIEW = -2;
    private static final int ERROR_NET_VIEW = -3;
    private static final int ERROR_VIEW = -4;


    public BaseRecyclerAdapter(Context context, List<SectionItem> list, ISectionFactory factory) {
        this.list = list;
        this.context = context;
        this.factory = factory;
    }

    public void setEmptyView(View view) {
        emptyView = view;
    }

    public void setNetErrorView(View view) {
        this.netErrorView = view;
    }

    public void setErrorView(View view) {
        this.errorView = view;
    }

    public void setFooterView(View view) {
        footerView = view;
    }

    public void setData(List<SectionItem> list) {
        isNewLoad = false;
        this.list = list;
        isErrorData = false;
        notifyData();
    }

    public void addData(List<SectionItem> list) {
        isNewLoad = false;
        this.list.addAll(list);
        isErrorData = false;
        notifyData();
    }

    public void errorData() {
        isNewLoad = false;
        isErrorData = true;
        this.list = null;
        notifyData();
    }


    public void notifyData() {
        super.notifyDataSetChanged();
    }

    public SectionItem getItem(int position) {
        if (this.list != null && this.list.size() > position) {
            return this.list.get(position);
        }
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public int getItemCount() {
        return isNewLoad ? 0 : (list == null || list.size() == 0 ? 1 : list.size() + (footerView == null ? 0 : 1));
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == EMPTY_VIEW) {
            RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            emptyView.setLayoutParams(lp);
            return new EmptyViewHolder(emptyView);
        } else if (viewType == ERROR_NET_VIEW) {
            RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            netErrorView.setLayoutParams(lp);
            return new EmptyViewHolder(netErrorView);
        } else if (viewType == ERROR_VIEW) {
            RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            errorView.setLayoutParams(lp);
            return new EmptyViewHolder(errorView);
        } else if (viewType == FOOTER_VIEW) {
            RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            footerView.setLayoutParams(lp);
            return new FooterViewHolder(footerView);
        } else {
            IView view = this.factory.createView(viewType);
            RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            view.setLayoutParams(lp);
            return new TimeLineViewHolder(view);
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof TimeLineViewHolder) {
            IView view = (IView) holder.itemView;
            view.setPosition(position);
            SectionItem item = getItem(position);
            view.update(item.data, item.extras);
        }
    }

    @Override
    public int getItemViewType(int position) {
        if (list == null || list.size() == 0) {
            if (!NetUtils.isNetworkAvailable(BaseApplication.getBaseApplication()) && netErrorView != null) {
                return ERROR_NET_VIEW;
            } else if (isErrorData) {
                return ERROR_VIEW;
            } else {
                return EMPTY_VIEW;
            }
        } else if (position < list.size()) {
            return getItem(position).type;
        } else {
            return FOOTER_VIEW;
        }
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if (manager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) manager);
            gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    return getItemViewType(position) < 0 ? gridManager.getSpanCount() : (spanSizeCallback == null ? 1 : spanSizeCallback.getSpanSize(getItemViewType(position)));
                }
            });
        }
    }


    public SpanSizeCallback spanSizeCallback;

    public void setSpanSizeCallback(SpanSizeCallback spanSizeCallback) {
        this.spanSizeCallback = spanSizeCallback;
    }

    public interface SpanSizeCallback {
        int getSpanSize(int type);
    }

    private class TimeLineViewHolder extends RecyclerView.ViewHolder {

        public TimeLineViewHolder(View itemView) {
            super(itemView);
        }
    }

    private class EmptyViewHolder extends RecyclerView.ViewHolder {

        public EmptyViewHolder(View itemView) {
            super(itemView);
        }
    }

    private class FooterViewHolder extends RecyclerView.ViewHolder {

        public FooterViewHolder(View itemView) {
            super(itemView);
        }
    }

    public void notifyDataRemoved(int position) {
        try {
            list.remove(position);
            notifyItemRemoved(position);
            if (position != list.size()) {
                notifyItemRangeChanged(position, list.size() - position);
            }
        } catch (Exception e) {
            Logger.e(e);
        }
    }
}
